package mobao.baseinfo.user.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import mobao.system.annotation.IgnoreCheck;
import mobao.system.annotation.SysLog;
import mobao.system.exception.MobaoException;
import mobao.system.token.AuthManager;
import mobao.utils.*;
import mobao.baseinfo.user.entity.SysUserT;
import mobao.baseinfo.user.service.SysUserSerivce;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.security.auth.message.AuthException;
import java.sql.Date;
import java.util.Optional;

@RequestMapping(value = "/sysUser")
@RestController
@Log4j2
@Api(value="系统用户相关接口",description = "系统用户相关接口")
public class SysUserController extends BaseController{
    @Autowired
    private SysUserSerivce sysUserSerivce;
    @Autowired
    private AuthManager authManager;


    @ApiOperation(value="查询所有系统用户", notes="根据分页进行查询,放入当前页page(从0开始)和每页显示数量size,返回" +
            "总数total和当前页page,查询总数size,查询数据结果Data,总共页数totalPage")
    @RequestMapping(value = "/list",method = RequestMethod.GET)
    @ResponseBody
    public R list(PageUtil pageUtil){
        SysUserT host = getCurrentUserInfo();
        log.info("用户[{}]查询第[{}]页[{}]条系统用户数据开始！",host.getUsername(),pageUtil.getPage(),pageUtil.getSize());
        Page page = sysUserSerivce.findAll(pageUtil.getPage(),pageUtil.getSize());
        log.info("用户[{}]查询到[{}]条系统用户数据结束,如下:[{}]",host.getUsername(),page.getContent().size(),page.getContent().toString());
        R r = R.ok("查询用户数据成功!");
        r.put("size",page.getSize());
        r.put("total",page.getTotalElements());
        r.put("totalPage",page.getTotalPages());
        r.put("page",pageUtil.getPage());
        r.put("data",page.getContent());
        return r;
    }
    @SysLog("根据ID查询用户信息")
    @ApiOperation(value="根据ID查询用户信息", notes="输入内容为返回内容")
    @RequestMapping(value = "/info/{userId}",method = RequestMethod.GET)
    @ResponseBody
    public R findById(@PathVariable Integer userId){
        SysUserT host = getCurrentUserInfo();
        log.info("用户[{}]根据ID[{}]查询用户信息开始!",host.getUsername(),userId);
        Optional<SysUserT> result;
         result= Optional.ofNullable(sysUserSerivce.findById(userId));
        if(result.isPresent()){
            R r = R.ok("查询用户信息成功!");
            log.info("用户[{}]根据ID[{}]查询到用户信息结束,如下：{}",host.getUsername(),userId,result.get().toString());
            r.put("data", result.get());
            return r;
        }
        log.info("用户[{}]根据ID[{}]查询用户信息结束,无相关用户信息!",host.getUsername(),userId);
        return R.error(Constants.FAIL,"查询不到相关用户信息!");
    }
    @SysLog("新增用户")
    @ApiOperation(value="新增用户", notes="用户注册必填信息有:用户名,密码,盐;状态: 0：禁用   1：正常")
    @RequestMapping(value = "/save",method = RequestMethod.POST)
    @ResponseBody
    public R addUser(SysUserT t){
        SysUserT host = getCurrentUserInfo();
        log.info("用户[{}]新增用户[{}]开始!",host.getUsername(),t.toString());
        t.setCreateTime(new Date(new java.util.Date().getTime()));
        t.setSalt(RandomTools.getRandomString(20));
        t.setPassword(SecureTools.pwdLock(t.getPassword(),t.getSalt()));
        t.setCreateUserId(host.getUserId());
        try{
            t= sysUserSerivce.save(t);
        }catch(Exception e){
            log.debug("用户[{}]新增用户[{}]异常:{}",host.getUsername(),t.toString(),e.toString());
            throw new MobaoException("新增用户异常,请与管理员联系!", ExceptionCode.JPA_EXCEPTION);
        }
        Optional<SysUserT> tOpt=Optional.ofNullable(t);
        if(tOpt.isPresent()){
            log.info("用户[{}]新增用户[{}]结束!",host.getUsername(),t.toString());
            R r = new R();
            r.put("data",tOpt.get());
            return r;
        }
        log.info("用户[{}]新增用户[{}]失败!",host.getUsername(),t.toString());
        return R.error(Constants.FAIL,"保存用户信息失败!");
    }
    @ApiOperation(value="用户注册", notes="用户注册必填信息有:用户名,密码,盐;状态: 0：禁用   1：正常")
    @RequestMapping(value = "/register",method = RequestMethod.PUT)
    @IgnoreCheck
    @ResponseBody
    public R register(@RequestBody SysUserT t){
        log.info("用户[{}]注册开始!",t.getUsername());
        t.setCreateTime(new Date(new java.util.Date().getTime()));
        t.setSalt(RandomTools.getRandomString(20));
        t.setPassword(SecureTools.pwdLock(t.getPassword(),t.getSalt()));
        try{
            t= sysUserSerivce.save(t);
        }catch(Exception e){
            log.error("用户[{}]注册异常:{}",t.getUsername(),e.toString());
            throw new MobaoException("用户未登陆或登陆过期,请重新登陆！", ExceptionCode.JPA_EXCEPTION);
        }
        Optional<SysUserT> tOpt=Optional.ofNullable(t);
        if(tOpt.isPresent()){
            log.info("用户[{}]注册结束!",t.getUsername());
            R r = R.ok("用户注册成功!");
            r.put("data",tOpt.get());
            return r;
        }
        log.info("用户[{}]注册失败!",t.getUsername());
        return R.error(Constants.FAIL,"用户注册失败!");
    }
    @SysLog("根据用户ID删除用户信息")
    @ApiOperation(value="根据用户ID删除用户信息", notes="根据ID物理删除相关用户信息,管理员账户不能删除!")
    @RequestMapping(value = "/del/{userId}",method = RequestMethod.POST)
    @ResponseBody
    public R del(@PathVariable Integer userId){
        SysUserT host = getCurrentUserInfo();
        log.info("用户[{}]删除ID为[{}]的用户开始!",host.getUsername(),userId);
        Optional<Integer> opt = Optional.ofNullable(userId);
        if(userId == getCurrentUserInfo().getUserId()){
            log.info("用户[{}]删除当前操作用户失败!",host.getUsername());
            return R.error(Constants.FAIL,"不能删除正在操作的用户!");
        }
        if(opt.isPresent() && opt.get().intValue() != 1){//排除管理员
            log.info("用户[{}]删除ID为[{}]的用户结束!",host.getUsername(),userId);
            try{
                sysUserSerivce.deleteById(userId);
            }catch (EmptyResultDataAccessException e){
                log.error("用户[{}]删除ID为[{}]的用户不存在!",host.getUsername(),userId);
                return R.error("删除的用户信息不存在!");
            }catch (Exception e){
                log.error("用户[{}]删除ID为[{}]的用户异常!{}",host.getUsername(),userId,e.getStackTrace());
                return R.error("删除用户信息异常!");
            }
            return new R();
        }
        log.info("用户[{}]删除管理员用户权限不足!",host.getUsername());
        return R.error(Constants.FAIL,"删除管理员信息权限不足!");
    }
    @SysLog("根据用户ID修改用户信息")
    @ApiOperation(value="根据用户ID修改用户信息", notes="输入内容限制为:邮箱,手机号,状态")
    @RequestMapping(value = "/update",method = RequestMethod.PUT)
    @ResponseBody
    public R update(@RequestBody SysUserT t){
        SysUserT host = getCurrentUserInfo();
        log.info("用户[{}]修改ID为[{}]的用户信息开始!",host.getUsername(),t.getUserId());
        try{
            sysUserSerivce.update(t);
        }catch (Exception e){
            log.error("用户[{}]修改ID为[{}]的用户信息异常!",host.getUsername(),t.getUserId());
            throw new MobaoException("更新用户状态异常,请与管理员联系!", ExceptionCode.JPA_EXCEPTION);
        }
        log.info("用户[{}]修改ID为[{}]的用户信息结束!",host.getUsername(),t.getUserId());
        return R.ok("修改用户信息成功");
    }
    @SysLog("修改密码操作")
    @ApiOperation(value="修改密码操作", notes="输入内容限制为:用户Id,旧密码,新密码")
    @RequestMapping(value = "/updatePwd",method = RequestMethod.POST)
    @ResponseBody
    public R updatePwd(String password,String newPassword){
        SysUserT host = getCurrentUserInfo();
        log.info("用户[{}]修改当前密码开始!",host.getUsername());
        try{
            SysUserT userT = sysUserSerivce.findById(host.getUserId());
            Optional<SysUserT> userTOpt = Optional.ofNullable(userT);
            if(userTOpt.isPresent()){
                String pwd = SecureTools.pwdLock(password,userTOpt.get().getSalt());
                if(pwd.equals(userTOpt.get().getPassword())){
                    String salt = RandomTools.getRandomString(20);
                    sysUserSerivce.updatePwd(host.getUserId(),SecureTools.pwdLock(newPassword,salt),salt);
                }else {
                    log.info("用户[{}]修改当前密码结束!原密码输入有误!",host.getUsername());
                    return R.error("密码输入错误!");
                }
            }else{
                log.info("用户[{}]修改当前密码结束!查询不到当前用户!",host.getUsername());
                return R.error("当前用户不存在!");
            }
        }catch (Exception e){
            throw new MobaoException("更新用户状态异常,请与管理员联系!", HttpStatus.EXPECTATION_FAILED.value());
        }
        return R.ok("当前用户密码修改成功!");
    }
    @SysLog("根据用户ID重置密码")
    @ApiOperation(value="根据用户ID重置密码", notes="输入内容限制为:用户Id,新密码")
    @RequestMapping(value = "/resetPwd",method = RequestMethod.POST)
    @ResponseBody
    public R resetPwd(Integer userId,String password){
        SysUserT host = getCurrentUserInfo();
        try{
            if(password != null && !"".equals(password)){
                    SysUserT userT = sysUserSerivce.findById(userId);
                    if(userT == null){
                        log.info("管理员用户[{}]重置ID[{}]密码结束!无当前用户信息!",host.getUsername(),userId);
                         return R.error("无当前用户信息!");
                    }
                    log.info("管理员用户[{}]重置ID[{}]密码开始!",host.getUsername(),userId);
                    String salt = RandomTools.getRandomString(20);
                    userT.setPassword(SecureTools.pwdLock(password,salt));
                    userT.setSalt(salt);
                    sysUserSerivce.update(userT);
            }else{
                log.info("管理员用户[{}]重置ID[{}]密码结束!设置密码不能为空!",host.getUsername(),userId);
                return R.error(Constants.FAIL,"设置密码不能为空!");
            }
        }catch (Exception e){
            log.error("管理员用户[{}]重置ID[{}]密码异常!{}",host.getUsername(),userId,e.toString());
            throw new MobaoException("重置用户密码异常,请与管理员联系!",ExceptionCode.JPA_EXCEPTION);
        }
        return R.ok("重置用户密码成功!");
    }
    /**
     * 用户登录
     * @param username
     * @param password
     * @return
     */
    @ApiOperation(value="用户登录操作", notes="输入内容限制为:用户名,用户密码")
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    @IgnoreCheck
    @ResponseBody
    public R login(String username,String password){
        SysUserT t = null;
        try{
            t = sysUserSerivce.getByUsername(username);
        }catch (Exception e){
            log.error("用户[{}]登录查询异常!",username);
            throw new MobaoException("用户登录查询异常!",ExceptionCode.JPA_EXCEPTION);
        }
        if(t == null){
            return R.error("当前用户名不存在!");
        }
        if(t.getStatus() != 1){
            return R.error("当前用户名未启用!");
        }
        String pwd = SecureTools.pwdLock(password,t.getSalt());
        if(pwd.equals(t.getPassword())){
           String token = authManager.signIn(t);
           log.info("用户名为{}的用户登录成功!",t.getUsername());
            R r = R.ok("登陆成功!");
            r.put("token",token);
            return r;
        }
        return R.error(Constants.FAIL,"用户密码错误!");
    }

    @ApiOperation(value="用户名验证操作", notes="返回code为0代表用户名可用！")
    @ApiImplicitParams(
            @ApiImplicitParam(name = "username",value = "用户名",required = true,dataType = "String",paramType = "path")
    )
    @RequestMapping(value = "/checkName/{username}",method = RequestMethod.GET)
    @IgnoreCheck
    @ResponseBody
    public R checkName(@PathVariable String username){
        if(sysUserSerivce.checkUsername(username)){
            return R.error(Constants.FAIL,"该用户已存在！");
        }
        return R.ok("该用户不存在,可以注册");
    }
    /**
     * 通过用户名,邮件,手机,状态等条件查找用户
     * @param t
     * @return
     */
    @ApiOperation(value="按条件查询", notes="通过用户名,邮件,手机,状态等条件查找用户")
    @RequestMapping(value = "/filter",method = RequestMethod.POST)
    @ResponseBody
    public R findByCondition(SysUserT t,PageUtil pageUtil){
        SysUserT host = getCurrentUserInfo();
        log.info("用户[{}]按条件查询用户信息开始!",host.getUsername());
        Page<SysUserT> page = null;
        try {
            page = sysUserSerivce.findByCondition(t, pageUtil.getPage(), pageUtil.getSize());
        }catch (Exception e){
            log.error("用户[{}]按条件查询用户信息异常!{}",host.getUsername(),e.toString());
            throw new MobaoException("查询异常!",ExceptionCode.JPA_EXCEPTION);
        }
        log.info("用户[{}]按条件查询用户信息结束!查询到[{}]条信息",host.getUsername(),page.getTotalElements());
        R r = R.ok("按条件查询成功!");
        r.put("size",page.getSize());
        r.put("total",page.getTotalElements());
        r.put("page",pageUtil.getPage());
        r.put("totalPage",page.getTotalPages());
        r.put("data",page.getContent());
        return r;
    };
    /**
     * 获取当前用户信息
     *
     * @return
     */
    @ApiOperation(value="获取当前用户信息", notes="根据taken获取！")
    @RequestMapping(value = "/getUserInfo",method = RequestMethod.POST)
    @ResponseBody
    public R getUserInfo(){
        SysUserT t = getCurrentUserInfo();
        //去除敏感信息
        t.setPassword("");
        t.setSalt("");
        if(t == null){
            return R.error(Constants.FAIL,"当前用户信息为空");
        }
        R r = R.ok("当前用户信息查询成功！");
        r.put("data",t);
        return r;
    }
    /**
     * 获取完整当前user信息
     */
    private SysUserT getCurrentUserInfo(){
        SysUserT t = null;
        try {
            t = authManager.getUserInfo();
        } catch (AuthException e) {
            log.error("获取当前用户信息异常:{}",e.toString());
            throw new MobaoException("获取当前信息失败!", HttpStatus.METHOD_FAILURE.value());
        }
        return t;
    }
    /**
     * 登出操作
     * 之后修改
     * @return
     */
    @SysLog("登出操作")
    @ApiOperation(value="登出操作", notes="根据taken获取！")
    @RequestMapping(value = "/logOut",method = RequestMethod.GET)
    @IgnoreCheck
    @ResponseBody
    public R logOut(){
        authManager.loginOff();
        return R.ok("退出登陆成功！");
    }

}
